package io.github.codelifeleno.jdbrelease.execute.StringStream;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 *
 */
public class RuleBasedStreamReader implements AutoCloseable {
    /**
     * 要处理的字符流
     */
    private final Reader reader;
    /**
     * 要处理的正向规则
     */
    private final PositiveRule positiveRule;
    /**
     * 要处理的逆向规则
     */
    private final NegativeRule negativeRule;

    /**
     * 拼接或推送的内容
     */
    private final StringBuilder buffer = new StringBuilder();

    /**
     * 是否触发了正向规则
     */
    private boolean isPositiveTriggered = false;
    /**
     * 是否触发了逆向规则
     */
    private boolean isNegativeTriggered = false;

    public RuleBasedStreamReader(Reader reader, PositiveRule positiveRule, NegativeRule negativeRule) {
        this.reader = reader;
        this.positiveRule = positiveRule;
        this.negativeRule = negativeRule;
    }

    /**
     * 读取并处理流，返回符合规则的内容列表
     */
    public List<String> readAll() throws IOException {
        List<String> result = new ArrayList<>();
        int charCode;
        while ((charCode = reader.read()) != -1) {
            processChar((char) charCode, result::add);
        }
        // 处理流末尾的剩余内容
        flushBuffer(result::add);
        return result;
    }

    /**
     * 流式处理（适合大文件）
     */
    public void stream(Consumer<String> consumer) throws IOException {
        int charCode;
        while ((charCode = reader.read()) != -1) {
            processChar((char) charCode, consumer);
        }
        flushBuffer(consumer);
    }

    /**
     * 每处理一个字符，对数据进行校验并推送数据
     *
     * @param c        这一个字符
     * @param consumer 自定义字符
     */
    private void processChar(char c, Consumer<String> consumer) {
        buffer.append(c);
        // 先检查逆向规则（优先级更高）
        if (negativeRule == null) {
            isNegativeTriggered = false;
        } else if (negativeRule.test(buffer, c)) {
            isNegativeTriggered = true;
            resetState();
            return;
        }
        // 检查正向规则
        if (positiveRule == null) {
            isPositiveTriggered = false;
            isNegativeTriggered = true;
        } else if (positiveRule.test(buffer, c)) {
            isPositiveTriggered = true;
            isNegativeTriggered = false;
        }
        // 判断是否满足释放条件
        if ((isPositiveTriggered && !isNegativeTriggered)) {

            if (buffer.toString().trim().isEmpty()) {
                return;
            }
            consumer.accept(buffer.toString());
            resetState();
        }
    }

    /**
     * 推送流
     *
     * @param consumer 自定义函数
     */
    private void flushBuffer(Consumer<String> consumer) {
        if (!buffer.isEmpty()) {
            if (buffer.toString().trim().isEmpty()) {
                return;
            }
            consumer.accept(buffer.toString());
        }
        resetState();
    }

    /**
     * 重置流状态
     */
    private void resetState() {
        buffer.setLength(0);
        isPositiveTriggered = false;
        isNegativeTriggered = false;
    }

    @Override
    public void close() throws IOException {
        reader.close();
    }
}